<template>
  <div
    ref="rootRef"
    class="suggest"
    v-loading:[loadingText]="loading"
    v-no-result:[noResultText]="noResult"
  >
    <ul class="suggest-list">
      <li
        class="suggest-item"
        v-if="singer"
        @click="() => {selectSinger(singer)}"
      >
        <div class="icon">
          <i class="icon-mine"></i>
        </div>
        <div class="name">
          <p class="text">{{ singer.name }}</p>
        </div>
      </li>
      <li
        class="suggest-item"
        v-for="song in songs"
        :key="song.id"
        @click="() => {selectSong(song)}"
      >
        <div class="icon">
          <i class="icon-music"></i>
        </div>
        <div class="name">
          <p class="text">
            {{song.singer}}-{{song.name}}
          </p>
        </div>
      </li>
      <div class="suggest-item" v-loading:[loadingText]="pullUpLoading" />
    </ul>
  </div>
</template>

<script>
import { ref, toRefs, reactive, watch, computed, nextTick } from 'vue'
import { search } from '../../service/search'
import { processSongs } from '../../service/song'
import usePullLoadEffect from './use-pull-load'

// loading指令
const useLoadingEffect = (data) => {
  const { singer, songs, hasMore } = toRefs(data)
  const loadingText = ref('')
  const noResultText = ref('抱歉，暂无搜索结果')
  const noResult = computed(() => {
    return !singer.value && !songs.value?.length && !hasMore.value
  })

  const loading = computed(() => {
    return !singer.value && !songs.value.length
  })

  return { loadingText, noResultText, noResult, loading }
}

// 下拉刷新和参数变化
const useQueryOrFreshEffect = (props, data, loading) => {
  const { singer, songs, hasMore } = toRefs(data)
  const page = ref(1)
  const manualLoading = ref(false)
  // 窃听搜索参数变化
  watch(() => props.query, async (newQuery) => {
    if (!newQuery) {
      return
    }
    await searchFirst()
  })
  // 阻止下拉刷新
  const preventPullUpload = computed(() => {
    return loading.value || manualLoading.value
  })
  const { rootRef, isPullUpload, scroll } = usePullLoadEffect(searchMore, preventPullUpload)

  // 是否能下拉刷新
  const pullUpLoading = computed(() => {
    return isPullUpload.value && hasMore.value
  })

  return {
    singer, songs, rootRef, pullUpLoading
  }

  // 加载更多
  async function searchMore () {
    if (!hasMore.value || !props.query) return
    page.value++
    const result = await search(props.query, page.value, props.showSinger)
    songs.value = songs.value.concat(await processSongs(result.songs))
    hasMore.value = result.hasMore
    await nextTick()
    await makeItScrollable()
  }
  // 是否能下拉滚动
  async function makeItScrollable () {
    if (scroll.value.maxScrollY >= -1) {
      manualLoading.value = true
      await searchMore()
      manualLoading.value = false
    }
  }
  // 清空数据
  async function searchFirst () {
    if (!props.query) {
      return
    }
    page.value = 1
    songs.value = []
    singer.value = null
    hasMore.value = true
    const result = await search(props.query, page.value, props.showSinger)
    songs.value = await processSongs(result.songs)
    singer.value = result.singer
    hasMore.value = result.hasMore
  }
}

// 点击事件
const useClickEffect = (emit) => {
  const selectSong = (song) => {
    console.log(song)
    emit('selectSong', song)
  }

  const selectSinger = (singer) => {
    emit('selectSinger', singer)
  }
  return { selectSong, selectSinger }
}

export default {
  name: 'suggest',
  props: {
    query: String,
    showSinger: {
      type: Boolean,
      default: true
    }
  },
  emits: ['selectSong', 'selectSinger'],
  setup (props, { emit }) {
    const data = reactive({
      singer: null,
      songs: [],
      hasMore: true
    })
    const {
      loadingText, noResultText, noResult, loading
    } = useLoadingEffect(data)

    const {
      singer, songs, rootRef, pullUpLoading
    } = useQueryOrFreshEffect(props, data, loading)

    const { selectSong, selectSinger } = useClickEffect(emit)

    return {
      singer,
      songs,
      loadingText,
      noResultText,
      noResult,
      loading,
      pullUpLoading,
      rootRef,
      selectSong,
      selectSinger
    }
  }
}
</script>

<style lang="scss" scoped>
  .suggest {
    height: 100%;
    overflow: hidden;
    .suggest-list {
      padding: 0 30px;
      .suggest-item {
        position: relative;
        display: flex;
        align-items: center;
        padding-bottom: 20px;
        .icon {
          flex: 0 0 30px;
          width: 30px;
          [class^="icon-"] {
            font-size: 14px;
            color: $color-text-d;
          }
        }
        .name {
          flex: 1;
          font-size: $font-size-medium;
          color: $color-text-d;
          overflow: hidden;
          .text {
            @include no-wrap();
          }
        }
      }
    }
  }
</style>
